package com.cb.serviceimpl;

import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeWapPayModel;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.request.AlipayTradeWapPayRequest;
import com.cb.config.AlipayConfig;
import com.cb.dao.AlipayDao;
import com.cb.dao.UserDao;
import com.cb.dao.UserFilmDao;
import com.cb.pojo.AllOrderListRedis;
import com.cb.pojo.OrderList;
import com.cb.pojo.ScreeninFormation;
import com.cb.pojo.User;
import com.cb.service.AlipayService;
import com.cb.service.UserFilmService;
import com.cb.service.UserService;
import io.swagger.models.auth.In;
import lombok.experimental.Accessors;
import org.apache.kafka.common.protocol.types.Field;
import org.reflections.serializers.XmlSerializer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.core.annotation.Order;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.kafka.support.serializer.StringOrBytesSerializer;
import org.springframework.stereotype.Service;
import springfox.documentation.spring.web.json.Json;

import javax.servlet.http.HttpServletRequest;
import java.io.Serializable;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

import static java.util.concurrent.TimeUnit.SECONDS;

@Service
public class AlipayServiceImpl implements AlipayService {

    @Autowired
    AlipayDao alipayDao;
    @Autowired
    UserDao userDao;
    @Autowired
    UserFilmDao userFilmDao;
    /** 调取支付宝接口 web端支付 */
    @Autowired
    @Qualifier("redisTemplateCustomize")
    private RedisTemplate<Object, Object> redisCacheTemplate;

    private String allOrderListRedis = "allOrderListRedis";

    @Override
    public String zhiFu(String OutTradeNo,String Subject,String TotalAmount,String Body,String TimeoutExpress,String ProductCode) throws AlipayApiException {
        AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.APP_ID, AlipayConfig.APP_PRIVATE_KEY, "json", AlipayConfig.CHARSET, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.sign_type);
        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
        AlipayTradeWapPayRequest request = new AlipayTradeWapPayRequest();

        AlipayTradeWapPayModel model = new AlipayTradeWapPayModel();
        model.setOutTradeNo(OutTradeNo);
        model.setSubject(Subject);
        model.setTotalAmount(TotalAmount);
        model.setBody(Body);
        model.setTimeoutExpress(TimeoutExpress);
        model.setProductCode(ProductCode);
        request.setBizModel(model);
        request.setNotifyUrl(AlipayConfig.notify_url);
        request.setReturnUrl(AlipayConfig.return_url);
        String form  = alipayClient.pageExecute(request).getBody();
        return form;
    }

    @Override
    public String scheduled(HashMap json, HttpServletRequest request) throws ParseException {
        OrderList orderList = new OrderList();
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String date = df.format(new Date());

        User user = new User();
        String username = String.valueOf(json.get("username"));
        user = userDao.selectUser(username);
        String ypid = String.valueOf(json.get("ypid"));
        double price = userFilmDao.selectFilmPrice(ypid);

        int tfvip;
        String now = df.format(new Date());
        Date nowDate = df.parse(now);
        Date endDate = userDao.selectEndVipTime(String.valueOf(json.get("username")));
        if (endDate == null || nowDate.getTime()>endDate.getTime()){
            tfvip = 0;
        }
        else{
            tfvip = 1;
        }
        orderList.setYyid(String.valueOf(json.get("yyid")))
                .setYyname(String.valueOf(json.get("yyname")))
                .setYpid(String.valueOf(json.get("ypid")))
                .setYpname(String.valueOf(json.get("ypname")))
                .setCcid(String.valueOf(json.get("ccid")))
                .setUsername(username)
                .setName(user.getName())
                .setPrice(Double.valueOf(String.valueOf(price)))
                .setTfvip(tfvip)
                .setRefundfee(0.0)
                .setChangefee(0.0)
                .setStatus("已支付")
                .setStatustime(df.parse(date))
                .setCreatetime(df.parse(date))
                .setLocate(String.valueOf(json.get("locate")));
        String id = "SX"+System.currentTimeMillis()+String.valueOf(json.get("ypid"));
        for (int i=0;i<10;i++){
            if (orderList.getUsername().charAt(i)=='@' && i!=9){
                for (int j=0 ;j<10-i-1;j++){
                    id+="0";
                }
                break;
            }
            id+=String.valueOf(orderList.getUsername().charAt(i));
        }
        System.out.println(id);
        orderList.setId(id);

        //double price = orderList.getPrice();
        if (orderList.getTfvip()==1){
            double amount = alipayDao.selectamount(orderList.getUsername());
            double discount = alipayDao.selectDiscount(orderList.getYyid());
            List<Integer> list = alipayDao.selectgrade();
            int grade = 0;
            for (int i=0;i<list.size()-1;i++){
                if (amount>=list.get(i) && amount<list.get(i+1)){
                    grade=i+1;
                    break;
                }
            }
            price = price - price*(discount*grade);
            orderList.setPrice(price);
        }
        redisCacheTemplate.opsForValue().set(id,orderList,300,SECONDS);
        String jsons = JSON.toJSONString(orderList);
        return jsons;
    }

    @Override
    public String filmPly(HashMap json, HttpServletRequest requests) throws ParseException,AlipayApiException {
        String ddid = String.valueOf(json.get("ddid"));
        OrderList orderList = (OrderList) redisCacheTemplate.opsForValue().get(ddid);
        alipayDao.insertOrderList(orderList);
        String ccid = orderList.getCcid();
        String locate = orderList.getLocate();
        ScreeninFormation screeninFormation = alipayDao.selectscreeninFormation(ccid);
        int number = alipayDao.selectnumber(screeninFormation.getYyid(),screeninFormation.getNumberid());
        int x = Integer.parseInt(String.valueOf((int)Math.sqrt(Double.valueOf(number))));
        int y=x;
        String list = alipayDao.selectList(Integer.parseInt(ccid));
        if(list==null){
            int[][] str = new int[x][y];
            int num=0;
            int x1=0,y1=-1;
            for (int i=0;i<locate.length();i++){
                if (locate.charAt(i)>='0'&&locate.charAt(i)<='9'){
                    num++;
                    y1++;
                    if (num>x && num%x==1){
                        x1++;
                    }
                    if (locate.charAt(i)!='0') {
                        str[x1][y1 % x] = Integer.parseInt(String.valueOf(locate.charAt(i)));
                    }
                }
            }
            String jsons = JSON.toJSONString(str);
            int i = alipayDao.updateList(Integer.parseInt(ccid),jsons);
        }
        else{
            int[][] str = new int[x][y];
            List<Integer> list1 = new ArrayList<>();
            for (int i=0;i<list.length();i++){
                if (list.charAt(i)>='0'&& list.charAt(i)<='9'){
                    list1.add(Integer.parseInt(String.valueOf(list.charAt(i))));
                }
            }
            //越界处理
            list1.add(0);
            int flag=0;
            for (int i=0;i<x;i++){
                for (int j=0;j<y;j++){
                    str[i][j]=list1.get(flag);
                    flag++;
                }
            }
            int num=0;
            int x1=0,y1=-1;
            for (int i=0;i<locate.length();i++){
                if (locate.charAt(i)>='0'&&locate.charAt(i)<='9'){
                    num++;
                    y1++;
                    if (num>x && num%x==1){
                        x1++;
                    }
                    if (locate.charAt(i)!='0') {
                        str[x1][y1 % x] = Integer.parseInt(String.valueOf(locate.charAt(i)));
                    }
                }
            }
            String jsons = JSON.toJSONString(str);
            int i = alipayDao.updateList(Integer.parseInt(ccid),jsons);
        }
        insertOrderlistRedis(orderList);
        return zhiFu(orderList.getId(),orderList.getYpname(),String.valueOf(orderList.getPrice()),"电影","2m",orderList.getYyid());
    }

    public void insertOrderlistRedis(OrderList orderList){
        AllOrderListRedis allOrderListRedis = new AllOrderListRedis();
        allOrderListRedis.setYpid(orderList.getYpid())
                .setYpname(orderList.getYpname());
        if (redisCacheTemplate.opsForZSet().size("allOrderListRedis")==null){
            allOrderListRedis.setNumber(1);
            alipayDao.insertAllOrderListRedis(allOrderListRedis);
            redisCacheTemplate.opsForZSet().add("allOrderListRedi",orderList.getYpname(),1);
        }
        else{
            double score =0;
            if(redisCacheTemplate.opsForZSet().score("allOrderListRedi",orderList.getYpname()) == null){
                score = 0;
            }
            else{
                score = Double.parseDouble(String.valueOf(redisCacheTemplate.opsForZSet().score("allOrderListRedi",orderList.getYpname())));
            }
            if (score==0){
                allOrderListRedis.setNumber(1);
                alipayDao.insertAllOrderListRedis(allOrderListRedis);
                redisCacheTemplate.opsForZSet().add("allOrderListRedi",orderList.getYpname(),1);
            }
            else{
                allOrderListRedis.setNumber((int)(score+1));
                alipayDao.updateAllOrderListRedis(allOrderListRedis);
                redisCacheTemplate.opsForZSet().add("allOrderListRedi",orderList.getYpname(),score+1);
            }
        }
    }


}
